import time
import threading
from utils.log_manager import logger
from PySide6.QtCore import QObject, QCoreApplication

class FakeMotorController(QObject):
    def __init__(self, port='USB', step_angle=1.8, subdivision=32, screw_pitch=0.5, transmission_ratio=1.0):
        # 模拟电机控制器，完全兼容真实控制器接口
        super().__init__()
        self.port = port
        self.step_angle = step_angle
        self.subdivision = subdivision
        self.screw_pitch = screw_pitch
        self.transmission_ratio = transmission_ratio
        self.max_range_mm = 25.0
        self.connected = False

        # 每轴的状态数据
        self.positions = {0: 0.0, 1: 0.0}      # 当前坐标 mm
        self.targets = {0: None, 1: None}      # 目标坐标 mm
        self.moving = {0: False, 1: False}
        self.speeds = {0: 1.0, 1: 1.0}         # 默认 1 mm/s
        self.accs = {0: 1.0, 1: 1.0}

        logger.log(QCoreApplication.translate("FakeMotorController","✅ 初始化 Fake 电机控制器"))
    
    def is_connected(self):
        """检查控制器是否实际连接"""
        try:
            return self.connected
        except Exception:
            return False

    def connect(self):
        self.connected = True
        logger.log(QCoreApplication.translate("FakeMotorController","🔌 模拟控制器连接成功"))
        return self.connected

    def disconnect(self):
        self.connected = False
        logger.log(QCoreApplication.translate("FakeMotorController","🔌 模拟控制器断开连接"))

    def set_speed(self, axis, acc_mm_s2, dec_mm_s2, vmax_mm_s):
        self.accs[axis] = acc_mm_s2
        self.speeds[axis] = min(vmax_mm_s, 2.5)  # 限速模拟
        logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 设置速度 acc={acc_mm_s2} dec={dec_mm_s2} vmax={vmax_mm_s} mm/s").format(axis=axis, acc_mm_s2=acc_mm_s2, dec_mm_s2=dec_mm_s2, vmax_mm_s=vmax_mm_s))

    def move_to(self, axis, target_mm):
        # if abs(target_mm) > self.max_range_mm:
        #     raise ValueError("超出允许移动范围 ±25mm")
        self._simulate_motion(axis, target_mm)
        logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 绝对移动到 {target_mm:.3f} mm").format(axis=axis, target_mm=target_mm))

    def move_by(self, axis, offset_mm):
        target = self.positions[axis] + offset_mm
        self.move_to(axis, target)
        logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 相对移动 {offset_mm:.3f} mm").format(axis=axis, offset_mm=offset_mm))

    def move_xy(self, x_mm, y_mm):
        """同时移动 X 和 Y 轴"""
        self.move_to(0, x_mm)
        self.move_to(1, y_mm)
        logger.log(QCoreApplication.translate("FakeMotorController","[Fake XY] 同时移动到 X={x_mm:.3f} mm, Y={y_mm:.3f} mm").format(x_mm=x_mm, y_mm=y_mm))

    def stop(self, axis):
        self.moving[axis] = False
        logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 停止").format(axis=axis))

    def halt_all(self):
        for axis in self.positions:
            self.stop(axis)
        logger.log(QCoreApplication.translate("FakeMotorController","🔴 模拟控制器急停所有轴"))

    def get_position(self, axis):
        return round(self.positions[axis], 3)

    def get_position_xy(self):
        """获取 XY 两轴当前位置"""
        return self.get_position(0), self.get_position(1)

    def set_position(self, axis, value_mm):
        self.positions[axis] = round(value_mm, 3)
        logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 手动设置当前位置为 {value_mm:.3f} mm").format(axis=axis, value_mm=value_mm))

    def is_moving(self, axis):
        return self.moving[axis]

    def is_any_axis_moving(self):
        """判断是否任一轴正在运动"""
        return any(self.moving.values())

    def wait_for_motion_done(self, axis, timeout=60):
        start = time.time()
        while self.moving[axis]:
            if time.time() - start > timeout:
                logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 等待超时").format(axis=axis))
                return False
            time.sleep(0.05)
        return True

    def home_axis(self, axis):
        # 自动归零逻辑：-30 → +30 → 中心 → 设置为0
        def _do_home():
            logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 自动归零开始").format(axis=axis))
            self.move_by(axis, -30)
            self.wait_for_motion_done(axis)
            p_neg = self.get_position(axis)
            time.sleep(0.3)

            self.move_by(axis, 30)
            self.wait_for_motion_done(axis)
            p_pos = self.get_position(axis)
            time.sleep(0.3)

            center = (p_neg + p_pos) / 2.0
            self.move_to(axis, center)
            self.wait_for_motion_done(axis)
            self.set_position(axis, 0.0)
            logger.log(QCoreApplication.translate("FakeMotorController","[Fake {axis}] 归零完成 负限: {p_neg:.3f} 正限: {p_pos:.3f} 中心: {center:.3f}").format(axis=axis, p_neg=p_neg, p_pos=p_pos, center=center))

        threading.Thread(target=_do_home, daemon=True).start()

    # ================= 内部模拟运动逻辑 =================

    def _simulate_motion(self, axis, target):
        def _move():
            self.moving[axis] = True
            pos = self.positions[axis]
            step = 0.01 * (1 if target > pos else -1)
            while abs(self.positions[axis] - target) > 0.01 and self.moving[axis]:
                self.positions[axis] += step
                time.sleep(0.01 / self.speeds[axis])
            self.positions[axis] = round(target, 3)
            self.moving[axis] = False

        threading.Thread(target=_move, daemon=True).start()

    def mm_to_steps(self, mm):
        """模拟换算（用于日志调试）"""
        return int(mm * self.subdivision / self.screw_pitch)

    def steps_to_mm(self, steps):
        return steps * self.screw_pitch / self.subdivision

    def debug_print_conversion(self):
        print(QCoreApplication.translate("FakeMotorController","[Fake] 1 mm ≈ {mm_to_steps} 步").format(mm_to_steps=self.mm_to_steps(1)))
